/*
 * 
 */
package mx.unam.acatlan.poo.poligonos;


/**
 * @author Carlos Alegría Galicia
 *
 */
public class PolígonoRegular {

	/** 
	 * El punto que representa la posición del polígono.
	 */
	private Punto posición = null;
	
	/**
	 * El número de lados del polígono
	 */
	private int lados = 0;
	
	/**
	 * El circumradio del polígono
	 */
	private float radio = 0;
	
	/**
	 * El área del polígono
	 */
	private float área = 0;
	
	/**
	 * El perímetro del polígono
	 */
	private float perímetro = 0;
	
	/**
	 * Crea un polígono regular con <code>lados</code> lados, localizado en
	 * <code>posición</code>, y de tamaño <code>radio</code>.
	 * 
	 * @param posición La ubicación del centro del polígono.
	 * @param lados    El número de lados del polígono.
	 * @param radio    El radio del polígono.
	 */
	public PolígonoRegular(Punto posición, int lados, float radio) {
		
		// utilizamos el seter para validar y establecer la posición del
		// polígono
		//
		setPosición(posición);
		
		// un polígono tiene al menos tres lados
		//
		if (lados < 3) {
			throw new IllegalArgumentException(
					"El número de lados debe ser al menos igual a tres");
		}
		this.lados = lados;
		
		// sólo consideramos radios mayores que cero
		//
		if (radio <= 0) {
			throw new IllegalArgumentException(
					"El radio del polígono debe ser meyor que cero");
		}
		this.radio = radio;
		
		// sabemos que la única propiedad de escritura es la posición del
		// polígono. ya que el perímetro no cambia cuando cambia la posición del
		// polígono, lo calculamos desde el consctructor 
		//
		this.perímetro = (float) (lados * 2 * radio
									* Math.sin(Math.PI / lados));
				
		// lo mismo pasa con el área del polígono, de forma que también lo
		// calculamos desde el constructor
		//
		this.área = (float) (0.5 * lados * radio * radio
								* Math.sin(2 * Math.PI / lados));
	}
	
	/**
	 * Obtiene la posición del polígono.
	 * 
	 * @return El punto que indica la posición del polígono. 
	 */
	public Punto getPosición() {
		Punto punto = null;
		try {
			punto = (Punto) this.posición.clone();
		} catch (CloneNotSupportedException e) {
		}
		return punto;
	}

	/**
	 * Establece la posición del polígono
	 * 
	 * @param punto El punto que indica la nueva posición del polígono
	 */
	public void setPosición(Punto punto) {
		if (punto == null) {
			throw new IllegalArgumentException(
					"El punto utilizado como posición no puede ser nulo");
		}
		this.posición.setX(punto.getX());
		this.posición.setY(punto.getY());
	}

	/**
	 * Obtiene el número de lados del polígono
	 * 
	 * @return El número de lados del polígono
	 */
	public int getLados() {
		return lados;
	}

	/**
	 * Obtiene el radio del polígono
	 * 
	 * @return El radio del polígono
	 */
	public float getRadio() {
		return radio;
	}

	/**
	 * Obtiene el área del polígono.
	 * 
	 * El área del polígono es calculada utilizando
	 * <pre>A = 1/2 * n * r ^ 2 * sen(2 * PI / n),</pre> donde A es el área del
	 * polígono, r el radio, y n el número de lados.  
	 * 
	 * @return El área del polígono
	 */
	public float getÁrea() {
		return área;
	}

	/**
	 * Obtiene el perímetro del polígono.
	 * 
	 * El perímetro del polígono es calculado utilizando
	 * <pre>P = 2 * n * r * sen(PI / n),</pre>
	 * donde P es el perímetro del polígono, n es el número de lados, y r es el
	 * radio.
	 * 
	 * @return El perímetro del polígono.
	 */
	public float getPerímetro() {
		return perímetro;
	}
}